/**
 * SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
 * SPDX-License-Identifier: Mulan PSL v2
 */
<template>
    <div class="model-repository-wrap">
        <common-title
            :title-name="_('模型仓库')" />
        <div class="model-repository-container">
            <!-- <empty-panel
                :title="_('暂时没有待部署模型')"
                :text="_('前往“训练任务列表”中注册已成功完成训练的模型，或直接上传开箱即用的模型')"
                v-if="showEmptyRepository"></empty-panel> -->
            <div class="table-data">
                <sf-grid>
                    <sf-toolbar ref="toolbar">
                        <sf-button
                            ref="submit"
                            class="creat-button btn-blank"
                            icon-cls="iconxinzeng"
                            @click="_addModel">
                            <lang>上传模型</lang>
                        </sf-button>
                        <sf-searchfield v-model="searchParams.keyword"
                                        class="pull-right"
                                        placeholder="请输入关键字"
                                        @clear="onEnterkey"
                                        @trigger="onEnterkey" />
                    </sf-toolbar>
                    <sf-table
                        ref="modelTable"
                        :options="options_fix"
                        :border="true"
                        @pagechange="_onPageChange"
                        @sizechange="_onSizeChange"
                        @toggleColsMenu="toggleColsMenu">
                        <sf-table-column :default-width="30"
                                         type="index">
                            <lang>序号</lang>
                        </sf-table-column>
                        <sf-table-column data-index="name"
                                         :default-width="80">
                            <lang>模型名称</lang>
                        </sf-table-column>
                        <sf-table-column data-index="sourceType"
                                         :default-width="80">
                            <lang>模型来源</lang>
                        </sf-table-column>
                        <sf-table-column data-index="taskName"
                                         :default-width="80">
                            <lang>所属任务</lang>
                        </sf-table-column>
                        <sf-table-column data-index="createTime"
                                         :default-width="100">
                            <lang>生成时间</lang>
                        </sf-table-column>
                        <sf-table-column data-index="opr"
                                         :default-width="120">
                            <lang>操作</lang>
                        </sf-table-column>
                        <template slot="sourceType"
                                  slot-scope="{record}">
                            <span>{{ !!record.sourceType?_('模型上传'):_('模型生成') }}</span>
                        </template>
                        <template slot="createTime"
                                  slot-scope="{value}">
                            <span>{{ encodeTime(value) }}</span>
                        </template>
                        <template slot="opr"
                                  slot-scope="{record}">
                            <div class="table-opr">
                                <a
                                    class="link-btn"
                                    href="javascript:void(0);"
                                    @click="_downloadFile(record)">
                                    <lang>下载</lang>
                                </a>
                                <!-- <a
                                    :href="`/training/v1/model/file/${record.id}`"
                                    download
                                    class="link-btn">
                                    <lang>下载</lang>
                                </a> -->
                                <a
                                    class="link-btn-disabled">
                                    <!--@click="_addWebService(record)">-->
                                    <lang>部署服务</lang>
                                </a>
                                <a
                                    class="link-btn"
                                    @click="_deleteModel(record)">
                                    <lang>删除</lang>
                                </a>
                            </div>
                        </template>
                    </sf-table>
                </sf-grid>
            </div>
        </div>
    </div>
</template>
<script>
import {
    encodeDate
} from 'src/util/format';

import { downloadFile } from 'src/util/blob_download';
import trainingUrlAdapter from 'src/home/mod_common/training_url_adapter';

const MODEL_URL = {
    get:trainingUrlAdapter('project'),
    update:trainingUrlAdapter('model'),
    delete:trainingUrlAdapter('model'),
    post:trainingUrlAdapter('model')
};

import deployUrlAdapter from 'src/home/mod_common/deploy_url_adapter';
import urlAdapter from 'src/home/mod_common/url_adapter';

const STREANUING_JOB = urlAdapter('streaming');



import commonTitle from '../component/common_title.vue';


import addModelForm from './label_form/add_model_form.vue';

const DOWNLOAD_FILE = trainingUrlAdapter('model/file');

import deployServiceForm from 'src/home/mod_cluster/project_manager/components/label_form/deploy_service_form.vue';
import streamServiceForm from 'src/home/mod_cluster/project_manager/components/label_form/stream_service_form.vue';
import selectServiceForm from 'src/home/mod_cluster/project_manager/components/label_form/select_service_form.vue';

// import EmptyPanel from 'src/components/empty_panel';

const PAGE_COUNT = 20;

export default {
    components:{
        commonTitle
    },

    data () {
        return {
            options_fix: {
                bufferView: false,

                // 配置这个后才可以实现保持勾选状态
                idProperty: 'id',
                selectionHide: true,
                forceFit: false,
                pagination: {
                    activePage: 1,
                    pageSize: PAGE_COUNT,
                    pageSizes: [Number('10'), Number('20'), Number('50')],
                    layout: [ 'pager', 'sizes', 'jumper']
                }
            },
            searchParams: {
                keyword: '',
                pageSize: PAGE_COUNT,
                pageNum: 0
            },
            /* eslint-disable no-magic-numbers */
            defaultWidth: 200,
            intervalTask: null,
            showEmptyRepository: false,
            emptyText: _('没有找到对应的模型'),
            imageList: []
        }
    },

    computed: {
        projectId () {
            return this.$route.query.projectId || '';
        }
    },


    mounted () {
        this.refreshGrid();
    },

    methods: {
        onEnterkey () {
            this.refreshGrid();
        },

        // 刷新grid
        async refreshGrid () {
            this.searchParams.projectId = this.projectId;
            let jsonData = await this.$ajax.get(`${MODEL_URL.get}/${this.projectId}/model`, this.searchParams);
            let table = this.$refs.modelTable;
            let {success, msg, data} = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                // @ts-ignore
                table.loadData([]);
                return;
            }
            if (!table) {
                return;
            }
            let {list} = data;
            table.getPagination().setTotal(data.total);

            // this.showEmptyRepository = list.length === 0;
            table.loadData(list || []);
        },

        encodeTime (time) {
            return encodeDate(time);
        },

        transformMetrics (record, params) {
            let value = '-';
            if (record.metrics) {
                try {
                    let metrics = JSON.parse(record.metrics);
                    value = metrics[params];
                } catch (e) {
                    value = '-';
                }
            }

            return value;
        },

        async _queryUpdateModel (ajaxParams) {
            let updateURL = `${MODEL_URL.update}/${ajaxParams.id}`;
            let params = {
                name:ajaxParams.name
            };
            let jsonData = await this.$ajax.post(updateURL, params);
            let {success, msg} = jsonData;
            if (!success) {
                return this.$showErr(msg || _('保存失败'));
            };
            this.$ok(_('更新模板成功'));
            this.refreshGrid();
        },

        // 选择服务弹窗
        _createSelectServiceFormWin () {
            if (!this.selectServiceFormWin) {
                this.selectServiceFormWin = this.$modal(selectServiceForm, {
                    autoDestory: true
                });
            }
            return this.selectServiceFormWin;
        },

        // 部署web服务弹窗
        _createDeployServiceFormWin () {
            if (!this.deployServiceFormWin) {
                this.deployServiceFormWin = this.$modal(deployServiceForm, {
                    autoDestory: true
                });
            }
            return this.deployServiceFormWin;
        },

        // 部署stream服务弹窗
        _createStreamServiceFormWin () {
            if (!this.streamServiceFormWin) {
                this.streamServiceFormWin = this.$modal(streamServiceForm, {
                    autoDestory: true
                });
            }
            return this.streamServiceFormWin;
        },

        _addWebService (record) {
            this._addWebServiceManager(record);
        },

        // 新增stream部署服务
        _addStreamServiceManager (record) {
            let formWin = this._createStreamServiceFormWin();
            formWin.formRoot.setJsonValue(record);
            formWin.open({
                reset: true,
                title: _('部署Stream Service服务'),
                buttons:[
                    { actionName: 'back', text: _('上一步') },
                    { actionName: 'submit', text: _('确定') },
                    'cancel'
                ],
                data:{
                    modelTitle:record.name,
                    resourceData :{
                        cpuNum: 1,
                        memorySize: 1
                    }
                },
                callback:(actionName)=>{
                    if (actionName === 'submit') {
                        if (!formWin.$refs.form.isValid()) {
                            this.$showErr(formWin.$refs.form.getInvalidMsgs());
                            return false;
                        }
                    let ajaxParams = formWin.formRoot.getJsonValue();
                        ajaxParams.modelName = record.name;
                        ajaxParams.projectId = this.projectId;
                        ajaxParams.modelId = record.id;
                        this.ajaxSubmitStreamService(ajaxParams, formWin);
                    } else if (actionName === 'back') {
                        formWin.hide();
                    } else if (actionName === 'cancel') {
                        formWin.hide();
                        this.selectServiceFormWin.hide();
                    }
                }
            });
        },

        // 新增/编辑算法的卡片信息
        async ajaxSubmitStreamService (params, formWin, fetch = 'post') {
            formWin.$mask();
            let jsonData = await this.$ajax[fetch](`${STREANUING_JOB}/project/${this.projectId}/job`, params);
            formWin.$unmask();
            let {success, msg} = jsonData;
            if (!success) {
                return this.$showErr(msg || _('部署服务失败'));
            }
            this.$ok(_('部署服务成功'));
            formWin.hide();
            this.selectServiceFormWin.hide();
            this.refreshGrid();

            let query = Object.assign(this.$route.query, {serviceIndex:1});
            this.$router.push({
                path:`/project_manager/project_index/service_manager`,
                query
            });
        },

        // 新增web部署服务
        _addWebServiceManager (record) {
            let formWin = this._createDeployServiceFormWin();
            formWin.formRoot.setJsonValue(record);
            formWin.open({
                reset: true,
                title: _('部署Web Service服务'),
                buttons:[
                    { actionName: 'back', text: _('上一步') },
                    { actionName: 'submit', text: _('确定') },
                    'cancel'
                ],
                data:{
                    modelTitle:record.name,
                    showImageList:record.predictor === 'custom',
                    formData:{
                        name:record.name,
                        readableName: '',
                        description:'',
                        protocol:1,
                        modelId:'',
                        default:{
                            cpuNum:1,
                            gpuNum:0,
                            memorySize:1,
                            minReplicas:1,
                            maxReplicas:1,
                            image:'',
                            modelUri:'',
                            modelName:'',
                            imageName:''
                        }
                    }
                },
                callback:(actionName)=>{
                    if (actionName === 'submit') {
                        if (!formWin.$refs.form.isValid()) {
                            this.$showErr(formWin.$refs.form.getInvalidMsgs());
                            return false;
                        }
                    let ajaxParams = formWin.formRoot.getJsonValue();
                        ajaxParams.default.modelUri = record.s3Address;
                        ajaxParams.default.modelName = record.name;
                        ajaxParams.projectId = this.projectId;
                        ajaxParams.default.modelId = record.id;
                        ajaxParams.default.predictor = record.predictor;
                        this.ajaxSubmitWebService(ajaxParams, formWin);
                    } else if (actionName === 'back') {
                        formWin.hide();
                    } else if (actionName === 'cancel') {
                        formWin.hide();
                        this.selectServiceFormWin.hide();
                    }
                }
            });
        },

        // 新增/编辑算法的卡片信息
        async ajaxSubmitWebService (params, formWin, fetch = 'post') {
            formWin.$mask();
            const SERVICE_ADD = deployUrlAdapter(`projects/${this.projectId}/services`);
            let jsonData = await this.$ajax[fetch](SERVICE_ADD, params);
            formWin.$unmask();
            let {success, msg} = jsonData;
            if (!success) {
                return this.$showErr(msg || _('部署服务失败'));
            }
            this.$ok(_('部署服务成功'));
            formWin.hide();
            this.selectServiceFormWin.hide();
            this.refreshGrid();
            let query = Object.assign(this.$route.query, {serviceIndex:0});
            this.$router.push({
                path:`/project_manager/project_index/service_manager`,
                query
            });
        },

        async ajaxDeleteModel (record) {
            const DELETE_URL = `${MODEL_URL.delete}/${record.id}`;
            this.$mask();
            let jsonData = await this.$ajax.delete(DELETE_URL, {});
            this.$unmask();
            let {success, msg} = jsonData;
            if (!success) {
                this.$showErr(msg || _('加载数据失败'));
                return;
            }
            this.$ok(_('删除模型成功'));
            this.refreshGrid();
        },

        _deleteModel (record) {
            this.$confirm({
                title: _('提示'),
                subTitle: _('确定要删除{0}模型吗？', record.name),
                msg: '',
                icon: 'warning',
                autoClose: true,
                callback: actionName => {
                    if (actionName === 'submit') {
                        this.ajaxDeleteModel(record);
                    }
                }
            });
        },

        _onPageChange (pageNum) {
            Object.assign(this.searchParams, {
                pageNum: pageNum - 1
            });
            this.refreshGrid();
        },

        _onSizeChange (nowPageIndex, nowPageSize) {
            Object.assign(this.searchParams, {
                pageNum: nowPageIndex - 1,
                pageSize: nowPageSize
            });
            this.refreshGrid();
        },

        toggleColsMenu () {
            let table = this.$refs.modelTable;
            table && table.resetColumnsWidth();
        },

        // 新增算法类型弹窗
        _createModelFormWin () {
            if (!this.modelFormWin) {
                this.modelFormWin = this.$modal(addModelForm, {
                    autoDestory: true
                });
            }
            return this.modelFormWin;
        },

        // 新增模型
        _addModel () {
            let formWin = this._createModelFormWin();
            let vm = this;
            formWin.open({
                reset: true,
                title: _('上传模型'),
                submit: () => {
                    let ajaxParams = formWin.formRoot.getJsonValue();
                    if (!ajaxParams.file) {
                        return this.$showErr(_('请上传模型文件'));
                    };
                    if (ajaxParams.fileMd5) {
                        this.ajaxSubmitModel(formWin);
                    };
                },
                uploadSuccessCallback (jsonData) {
                    let {success, msg} = jsonData;
                    if (!success) {
                        return vm.$showErr(msg || _('保存失败'));
                    }
                    vm.$ok(msg || _('保存成功'));
                    formWin.hide();
                    vm.refreshGrid();
                },
                uploadFailureCallback (jsonData) {
                    vm.$showErr(jsonData.msg || _('上传模型失败'));
                    formWin.hide();
                }
            });
        },

        // 新增模型文件
        async ajaxSubmitModel (formWin) {
            formWin.formRoot.beginUpload();
        },

        _downloadFile (record) {
            let fileName = `${record.originModelName}`;
            downloadFile(`${DOWNLOAD_FILE}/${record.id}`, 'get', fileName);
        }
    },



    beforeDestroy () {
        if (this.intervalTask) {
            this.intervalTask.stop();
            this.intervalTask = null;
        }
    }
};
</script>
<style lang="less">
    .model-repository-wrap{
        height: calc(100% - 17px);
        width: calc(100% - 40px);
    }

    .model-repository-container{
        height: calc(100% - 65px);
        background: #fff;
        flex: 1;
        overflow: auto;
        border: 1px solid #ddd;
        .status-0{
            color: #1DB83F
        }
        .status-1{
            color: #204ed9;
        }
        .status-2{
            color: #DE1B1B;
        }
        .table-data {
            height: 100%;
            width: 100%;
            .sfv-grid {
                /* border: none; */
                height: 100%;
                display: flex;
                flex-direction: column;

                .sfv-table {
                    flex: 1;
                }
            }
        }
    }
     @media screen and (max-width: 1366px) {
        .model-repository-container{
            max-width: 1063px;
        }
    }
    .link-btn-disabled {
        opacity: .3;
        color: #262f40;
    }

</style>
